package phases

import (
	"cke.io/ckectl/app/cmd/options"
	kubeoptions "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
	"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"

	addonsPhase "cke.io/ckectl/app/cmd/phases/up/addons"
	etcdPhase "cke.io/ckectl/app/cmd/phases/up/etcd"
	kubeMasterPhase "cke.io/ckectl/app/cmd/phases/up/kube-master"
	kubeNodePhase "cke.io/ckectl/app/cmd/phases/up/kube-node"
	monitorsPhase "cke.io/ckectl/app/cmd/phases/up/monitors"
	networkPhase "cke.io/ckectl/app/cmd/phases/up/network"
	preparePhase "cke.io/ckectl/app/cmd/phases/up/prepare"
	storagePhase "cke.io/ckectl/app/cmd/phases/up/storage"
	controllerPhase "cke.io/ckectl/app/cmd/phases/up/controller"
	componentsPhase "cke.io/ckectl/app/cmd/phases/up/components"
)

// NewEtcdPhase creates a kubeadm workflow phase that implements handling of etcd.
func NewAddonPhase() workflow.Phase {
	return workflow.Phase{
		Name:    "addons",
		Short:   "Write kubelet settings and (re)start the kubelet",
		Long:    "Write a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)start kubelet.",
		Phases: []workflow.Phase{
			addonsPhase.NewPspPhase(),
			addonsPhase.NewAddonsPhase(),
			addonsPhase.NewCloudControllerManagerPhase(),
		},
	}
}

// NewEtcdPhase creates a kubeadm workflow phase that implements handling of etcd.
func NewStoragePhase() workflow.Phase {
	return workflow.Phase{
		Name:    "storage",
		Short:   "Write kubelet settings and (re)start the kubelet",
		Long:    "Write a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)start kubelet.",
		Phases: []workflow.Phase{
			storagePhase.NewFlexdriverPhase(),
			storagePhase.NewProvisionerPhase(),
			storagePhase.NewScriptPhase(),
			storagePhase.NewProvisionerPodPhase(),
			storagePhase.NewCSIPhase(),
		},
	}
}

// NewEtcdPhase creates a kubeadm workflow phase that implements handling of etcd.
func NewEtcdPhase() workflow.Phase {
	return workflow.Phase{
		Name:    "etcd",
		Short:   "Write kubelet settings and (re)start the kubelet",
		Long:    "Write a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)start kubelet.",
		Phases: []workflow.Phase{
			etcdPhase.NewEtcdPhase(),
		},
	}
}

// NewEtcdPhase creates a kubeadm workflow phase that implements handling of etcd.
func NewPreparePhase() workflow.Phase {
	return workflow.Phase{
		Name:    "prepare",
		Short:   "Write kubelet settings and (re)start the kubelet",
		Long:    "Write a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)start kubelet.",
		Phases: []workflow.Phase{
			preparePhase.NewDockerPhase(),
			preparePhase.NewInitNodePhase(),
			preparePhase.NewNodeParameterPhase(),
			preparePhase.NewLoadImagesPhase(),
			preparePhase.NewNtpPhase(),
			preparePhase.NewSwapPhase(),
		},
		InheritFlags: []string{
			options.LocalIp,
			options.LocalHostName,
			options.AnsibleMounts,
			options.AllowKnowHosts,
			options.AllKnowDomains,
			options.InsecureRegistry,
			options.DockerPreconfiged,
			options.UseHyperKubeImage,
			kubeoptions.CfgPath,
			options.AnsibleImageName,
			kubeoptions.KubernetesVersion,
		},
	}
}

// NewEtcdPhase creates a kubeadm workflow phase that implements handling of etcd.
func NewMonitorsPhase() workflow.Phase {
	return workflow.Phase{
		Name:    "monitors",
		Short:   "Write kubelet settings and (re)start the kubelet",
		Long:    "Write a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)start kubelet.",
		Phases: []workflow.Phase{
			monitorsPhase.NewKubernetesRestartPhase(),
			monitorsPhase.NewCkeMonitorPhase(),
			monitorsPhase.NewBackupEtcdDataPhase(),
			monitorsPhase.NewJobExecutorPhase(),
		},
	}
}

// NewEtcdPhase creates a kubeadm workflow phase that implements handling of etcd.
func NewKubeMasterPhase() workflow.Phase {
	return workflow.Phase{
		Name:    "kube-master",
		Short:   "Write kubelet settings and (re)start the kubelet",
		Long:    "Write a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)start kubelet.",
		Phases: []workflow.Phase{
			kubeMasterPhase.NewKeepalivedPhase(),
			kubeMasterPhase.NewKubeMasterPhase(),
			kubeMasterPhase.NewClusterRolesPhase(),
		},
	}
}

// NewEtcdPhase creates a kubeadm workflow phase that implements handling of etcd.
func NewKubeNodePhase() workflow.Phase {
	return workflow.Phase{
		Name:    "kube-node",
		Short:   "Write kubelet settings and (re)start the kubelet",
		Long:    "Write a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)start kubelet.",
		Phases: []workflow.Phase{
			kubeNodePhase.NewKubeNodePhase(),
		},
	}
}


// NewEtcdPhase creates a kubeadm workflow phase that implements handling of etcd.
func NewNetworkPhase() workflow.Phase {
	return workflow.Phase{
		Name:    "network",
		Short:   "Write kubelet settings and (re)start the kubelet",
		Long:    "Write a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)start kubelet.",
		Phases: []workflow.Phase{
			networkPhase.NewCniPhase(),
		},
	}
}

func NewControllerPhase() workflow.Phase {
	return workflow.Phase{
		Name:    "controller",
		Short:   "Write kubelet settings and (re)start the kubelet",
		Long:    "Write a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)start kubelet.",
		Phases: []workflow.Phase{
			controllerPhase.NewControllerPhase(),
		},
	}
}

// NewComponentsPhase creates a kubeadm workflow phase that implements handling of Components.
func NewComponentsPhase() workflow.Phase {
	return workflow.Phase{
		Name:    "components",
		Short:   "Install components",
		Long:    "Install components.",
		Phases: []workflow.Phase{
			componentsPhase.NewComponentsPhase(),
		},
	}
}
